"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 故障&可靠性测试
Case Name   : 备机表空间目录权限不同，进行创建表空间
Create At   : 2022/04/22
Owner       : @peilinqian
Description :
    0、备机创建目录;
    1、修改备机表空间目录权限为000，创建表空间;
    修改目录为700、重启恢复备机
    2、修改备机表空间目录权限为100，创建表空间;
    修改目录为700、重启恢复备机
    3、修改备机表空间目录权限为200，创建表空间;
    修改目录为700、重启恢复备机
    4、修改备机表空间目录权限为300，创建表空间;
    修改目录为700、重启恢复备机
    5、修改备机表空间目录权限为400，创建表空间;
    6、创建表并插入一定量数据;
    7、修改备机表空间目录权限为500，创建表空间;
    8、修改备机表空间目录权限为600，创建表空间;
Expect      :
    0、备机创建目录;创建成功
    1、修改备机表空间目录权限为000，创建表空间;创建成功、备机异常
    修改目录为700、重启恢复备机成功
    2、修改备机表空间目录权限为100，创建表空间;创建成功、备机异常
    修改目录为700、重启恢复备机成功
    3、修改备机表空间目录权限为200，创建表空间;创建成功、备机异常
    修改目录为700、重启恢复备机成功
    4、修改备机表空间目录权限为300，创建表空间;创建成功、备机异常
    修改目录为700、重启恢复备机成功
    5、修改备机表空间目录权限为400，创建表空间;创建成功、备机正常
    6、创建表并插入一定量数据; 操作成功
    7、修改备机表空间目录权限为500，创建表空间;创建成功、备机正常
    8、修改备机表空间目录权限为600，创建表空间;创建成功、备机正常
History     :
    modified：2022/05/18 by pw5328113;优化用例，修改teardown断言信息
"""

import os
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.CommonSH import RestartDbCluster
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class DbSysCase270(unittest.TestCase):
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.pri_dbuser = Node(node='PrimaryDbUser')
        self.sta1_dbuser = Node(node='Standby1DbUser')
        self.sta2_dbuser = Node(node='Standby2DbUser')
        self.sta1_root = Node(node='Standby1Root')
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.constant = Constant()
        self.com = Common()
        self.tbspc_name = 'tbspc_dbsys270'
        self.table_name = 't_dbsys270'
        self.tbspc_path = os.path.join(os.path.dirname(
            macro.DB_INSTANCE_PATH), 'tbspc_dbsys270')
        self.create_sql = f"create tablespace {self.tbspc_name} " \
            f"location '{self.tbspc_path}';"
        self.drop_sql = f"drop tablespace if exists {self.tbspc_name};"
        self.max_num = 10000
        self.create_tb_sql = f'drop table if exists {self.table_name};' \
            f'create table {self.table_name}(id int, name text) ' \
            f'tablespace {self.tbspc_name};'
        self.insert_sql = f"insert into {self.table_name} " \
            f"select generate_series(1, {self.max_num})," \
            f"'name-'||generate_series(1, {self.max_num});"
        self.select_sql = f'select count(*) from {self.table_name};' \
            f'drop table {self.table_name}'
        self.chmod_cmd = f'chmod authority {self.tbspc_path} &&' \
            f'ls -al {os.path.dirname(self.tbspc_path)} ' \
            f'|grep {self.tbspc_name}'

    def test_main(self):
        step_txt = '----step0：备机创建目录;expect:创建成功----'
        self.log.info(step_txt)
        mkdir_cmd = f'mkdir {self.tbspc_path}'
        self.log.info(mkdir_cmd)
        mkdir_result = self.sta1_dbuser.sh(mkdir_cmd).result()
        self.log.info(mkdir_result)

        step_txt = '----step1：修改备机表空间目录权限为000，创建表空间;expect:创建成功、备机异常----'
        self.log.info(step_txt)
        create_msg = self.chmod_create(000)
        self.assertIn('d---------', create_msg[0], "执行失败" + step_txt)
        self.assertIn(self.constant.CREATE_TBLSPACE_SUCCESS_MSG,
                      create_msg[1], "执行失败" + step_txt)
        self.assertFalse(create_msg[2], "执行失败" + step_txt)

        self.log.info("----恢复备机及清理表空间----")
        recovery_result = self.recovery()
        self.assertTrue(recovery_result, "执行失败" + step_txt + "后恢复环境")

        step_txt = '----step2：修改备机表空间目录权限为100，创建表空间;expect:创建成功、备机异常----'
        self.log.info(step_txt)
        create_msg = self.chmod_create(100)
        self.assertIn('d--x------', create_msg[0], "执行失败" + step_txt)
        self.assertIn(self.constant.CREATE_TBLSPACE_SUCCESS_MSG,
                      create_msg[1], "执行失败" + step_txt)
        self.assertFalse(create_msg[2], "执行失败" + step_txt)

        self.log.info("----恢复备机及清理表空间----")
        recovery_result = self.recovery()
        self.assertTrue(recovery_result, "执行失败" + step_txt + "后恢复环境")

        step_txt = '----step3：修改备机表空间目录权限为200，创建表空间;expect:创建成功、备机异常----'
        self.log.info(step_txt)
        create_msg = self.chmod_create(200)
        self.assertIn('d-w-------', create_msg[0], "执行失败" + step_txt)
        self.assertIn(self.constant.CREATE_TBLSPACE_SUCCESS_MSG,
                      create_msg[1], "执行失败" + step_txt)
        self.assertFalse(create_msg[2], "执行失败" + step_txt)

        self.log.info("----恢复备机及清理表空间----")
        recovery_result = self.recovery()
        self.assertTrue(recovery_result, "执行失败" + step_txt + "后恢复环境")

        step_txt = '----step4：修改备机表空间目录权限为300，创建表空间;expect:创建成功、备机异常----'
        self.log.info(step_txt)
        create_msg = self.chmod_create(300)
        self.assertIn('d-wx------', create_msg[0], "执行失败" + step_txt)
        self.assertIn(self.constant.CREATE_TBLSPACE_SUCCESS_MSG,
                      create_msg[1], "执行失败" + step_txt)
        self.assertFalse(create_msg[2], "执行失败" + step_txt)

        self.log.info("----恢复备机及清理表空间----")
        recovery_result = self.recovery()
        self.assertTrue(recovery_result, "执行失败" + step_txt + "后恢复环境")

        step_txt = '----step5：修改备机表空间目录权限为400，创建表空间;expect:创建成功、备机正常----'
        self.log.info(step_txt)
        create_msg = self.chmod_create(400)
        self.assertIn('dr--------', create_msg[0], "执行失败" + step_txt)
        self.assertIn(self.constant.CREATE_TBLSPACE_SUCCESS_MSG,
                      create_msg[1], "执行失败" + step_txt)
        self.assertTrue(create_msg[2], "执行失败" + step_txt)

        step_txt = '----step6:创建表并插入一定量数据; expect:操作成功----'
        self.log.info(step_txt)
        self.log.info('--在tablespace上创建表--')
        create_result = self.pri_sh.executDbSql(self.create_tb_sql)
        self.log.info(create_result)
        self.assertIn(self.constant.TABLE_CREATE_SUCCESS, create_result,
                      "执行失败" + step_txt)
        self.log.info('--在tablespace上创建的表循环插入数据--')
        insert_result = self.pri_sh.executDbSql(self.insert_sql)
        self.log.info(insert_result)
        self.assertIn(self.constant.insert_success_msg, insert_result,
                      "执行失败" + step_txt)
        select_result = self.pri_sh.executDbSql(self.select_sql)
        self.log.info(select_result)
        self.assertEqual(str(self.max_num),
                         select_result.splitlines()[2].strip(),
                         "执行失败" + step_txt)

        step_txt = '----删除表空间;expect:删除成功----'
        self.log.info(step_txt)
        drop_result = self.pri_sh.executDbSql(self.drop_sql)
        self.log.info(drop_result)
        self.assertIn(self.constant.drop_tablespace_success_msg, drop_result,
                      "执行失败" + step_txt)

        step_txt = '----step7：修改备机表空间目录权限为500，创建表空间;expect:创建成功、备机正常----'
        self.log.info(step_txt)
        create_msg = self.chmod_create(500)
        self.assertIn('dr-x------', create_msg[0], "执行失败" + step_txt)
        self.assertIn(self.constant.CREATE_TBLSPACE_SUCCESS_MSG,
                      create_msg[1], "执行失败" + step_txt)
        self.assertTrue(create_msg[2], "执行失败" + step_txt)

        step_txt = '----删除表空间;expect:删除成功----'
        self.log.info(step_txt)
        drop_result = self.pri_sh.executDbSql(self.drop_sql)
        self.log.info(drop_result)
        self.assertIn(self.constant.drop_tablespace_success_msg, drop_result,
                      "执行失败" + step_txt)

        step_txt = '----step8：修改备机表空间目录权限为600，创建表空间;expect:创建成功、备机正常----'
        self.log.info(step_txt)
        create_msg = self.chmod_create(600)
        self.assertIn('drw-------', create_msg[0], "执行失败" + step_txt)
        self.assertIn(self.constant.CREATE_TBLSPACE_SUCCESS_MSG,
                      create_msg[1], "执行失败" + step_txt)
        self.assertTrue(create_msg[2], "执行失败" + step_txt)

    def chmod_create(self, authority):
        """
        :param authority: 赋权权限
        :return: 赋权结果、创建表空间结果、数据库状态
        """
        self.log.info(f'--修改权限为{authority}--')
        chmod_cmd = self.chmod_cmd.replace('authority', str(authority))
        chmod_result = self.com.get_sh_result(self.sta1_root, chmod_cmd)
        self.log.info('--创建表空间--')
        create_result = self.pri_sh.executDbSql(self.create_sql)
        self.log.info(self.create_sql)
        self.log.info('--查询主备状态--')
        status = self.pri_sh.getDbClusterStatus('status')
        return chmod_result, create_result, status

    def recovery(self):
        """
        :return: 数据库集群恢复及表空间清理结果是否正常
        """
        chmod_cmd = self.chmod_cmd.replace('authority', '700')
        self.com.get_sh_result(self.sta1_root, chmod_cmd)
        self.log.info("--重启数据库--")
        start_result = self.pri_sh.startDbCluster()
        self.log.info("--删除表空间--")
        drop_result = self.pri_sh.executDbSql(self.drop_sql)
        self.log.info(drop_result)
        if self.constant.drop_tablespace_success_msg in drop_result \
                and start_result:
            return True
        else:
            return False

    def tearDown(self):
        self.log.info("----this is tearDown----")
        step1_txt = '----清理表空间; expect:成功----'
        self.log.info(step1_txt)
        clean_result = self.pri_sh.executDbSql(self.drop_sql)
        self.log.info(clean_result)
        step2_txt = '----删除表空间路径; expect:成功----'
        self.log.info(step2_txt)
        del_cmd = f"rm -rf {self.tbspc_path}; " \
            f"if [ -d {self.tbspc_path} ]; then echo 'exists'; " \
            f"else echo 'not exists'; fi;"
        self.log.info(del_cmd)
        del_result1 = self.pri_dbuser.sh(del_cmd).result()
        del_result2 = self.sta1_dbuser.sh(del_cmd).result()
        del_result3 = self.sta2_dbuser.sh(del_cmd).result()
        self.log.info(del_result1)
        self.log.info(del_result2)
        self.log.info(del_result3)

        self.log.info(f'-----{os.path.basename(__file__)} end-----')
        self.assertIn(self.constant.drop_tablespace_success_msg, clean_result,
                      "执行失败" + step1_txt)
        self.assertEqual('not exists', del_result1, "执行失败" + step2_txt)
        self.assertEqual('not exists', del_result2, "执行失败" + step2_txt)
        self.assertEqual('not exists', del_result3, "执行失败" + step2_txt)
